// 防抖：防抖指的是在事件触发n秒后再执行回调，如果在n秒内再次被触发，则重新计算时间。
// 为什么需要防抖：就拿用户登录来说，如果不做防抖操作，多次点击登入按钮就会多次请求后台，
// 既会造成不必要的性能消耗也会造成用户体验的不好
// 防抖在连续的事件，只需触发一次回调的场景有：
// 搜索框搜索输入。只需用户最后一次输入完，再发送请求。
// 窗口大小的改变resize。只需窗口调整完成后，计算窗口大小。防止重复渲染。
// 登录、发短信等按钮避免用户点击太快，以致于发送了多次请求，需要防抖。
// 实现过程：封装一个函数并传递两个参数，
// 第一个参数是需要调用的函数或者请求，第二个参数是延迟多少毫秒才执行函数
// 在函数里先定义一个空变量，再return一个匿名函数，在该函数中先判断定义的变量是否为空，
// 为空就添加一个定时器，不为空就清除定时器
// fn代表有个函数，里面可能会频繁发生回调或ajax
// delay表示间隔多少毫秒才触发，默认200毫秒
export function debounce(fn: Function, delay = 200) {//fn是需要防抖的函数，delay是延迟多少毫秒执行fn
    let timer: ReturnType<typeof setTimeout> | null = null;
    // let timer: NodeJS.Timeout | null = null;
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            fn.apply(fn, arguments);
            timer = null;
        }, delay)
        console.log(timer, "timer");

    }
}
// 节流：节流是指如果持续触发某个事件，则每隔n秒执行一次
// fn代表可能会频繁发生回调或ajax请求的函数
// delay表示间隔多少毫秒才触发，默认100毫秒
// 节流在间隔一段时间执行一次回调的场景有：
// 滚动加载，加载更多或滚到底部监听
// 搜索框，搜索联想功能
// 实现过程：封装一个函数并传递两个参数，
// 第一个参数是需要调用的函数或者请求，第二个参数是延迟多少毫秒才执行函数
// 在函数里先定义一个空变量，再return一个匿名函数，在该函数中先判断定义的变量是否为空，
// 为空就执行定时器，不为空就不执行定时器而不是像防抖一样清除定时器
export function throttle(fn: Function, delay = 100) {
    //首先设定一个变量，在没有执行我们的定时器为null
    let timer: ReturnType<typeof setTimeout> | null = null;
    return function () {
        //当我们发现这个定时器存在时，则表示定时器已经在运行中，需要返回
        if (timer) return;
        timer = setTimeout(() => {
            fn.apply(fn, arguments);
            timer = null;
        }, delay)
    }
}